<template>
	<view>
		<view class="uni-header">
			<view class="uni-group">
				<view class="uni-title"></view>
				<view class="uni-sub-title"></view>
			</view>
			<view class="uni-group">
				<input class="uni-search" type="text" v-model="query" @confirm="search" placeholder="请输入搜索内容" />
				<button class="uni-button" type="default" size="mini" @click="search">搜索</button>
				<button class="uni-button" type="default" size="mini" @click="navigateTo('./add')">新增</button>
				<!-- <button class="uni-button" type="default" size="mini" :disabled="!selectedIndexs.length"
					@click="delTable">批量删除</button> -->
				<download-excel class="hide-on-phone" :fields="exportExcel.fields" :data="exportExcelData"
					:type="exportExcel.type" :name="exportExcel.filename">
					<button class="uni-button" type="primary" size="mini">导出 Excel</button>
				</download-excel>
			</view>
		</view>
		<view class="uni-container">
			<unicloud-db ref="udb" :collection="collectionList"
				field="provider,uni_platform,type,order_no,refund_count,create_date,notify_date,refund_list,provider_appid,original_data,appid,transaction_id,device_id,client_ip,openid,err_msg,user_id,status,nickname,description,total_fee,refund_fee,user_order_success,custom,pay_date,cancel_date,out_trade_no"
				:where="where" page-data="replace" :orderby="orderby" :getcount="true" :page-size="options.pageSize"
				:page-current="options.pageCurrent" v-slot:default="{data,pagination,loading,error,options}"
				:options="options" loadtime="manual" @load="onqueryload">
				<uni-table ref="table" :loading="loading" :emptyText="error.message || '没有更多数据'" border stripe
					type="selection" @selection-change="selectionChange">
					<uni-tr>
						<uni-th align="center" filter-type="select" :filter-data="options.filterData.provider_localdata"
							@filter-change="filterChange($event, 'provider')">支付方式</uni-th>
						<uni-th align="center" filter-type="select" :filter-data="options.filterData.status_localdata"
							@filter-change="filterChange($event, 'status')">订单状态</uni-th>
						<uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'nickname')"
							sortable @sort-change="sortChange($event, 'nickname')">报名用户</uni-th>
						<uni-th align="center" filter-type="search" @filter-change="filterChange($event, 'description')"
							sortable @sort-change="sortChange($event, 'description')">支付描述</uni-th>
						<uni-th align="center" filter-type="range" @filter-change="filterChange($event, 'total_fee')"
							sortable @sort-change="sortChange($event, 'total_fee')">支付金额</uni-th>
						<uni-th align="center" filter-type="range" @filter-change="filterChange($event, 'refund_fee')"
							sortable @sort-change="sortChange($event, 'refund_fee')">退款金额</uni-th>
						<uni-th align="center" sortable
							@sort-change="sortChange($event, 'user_order_success')">付款后报名是否成功</uni-th>
						<uni-th align="center" sortable @sort-change="sortChange($event, 'custom')">报名失败原因</uni-th>
						<uni-th align="center" filter-type="timestamp" @filter-change="filterChange($event, 'pay_date')"
							sortable @sort-change="sortChange($event, 'pay_date')">支付时间</uni-th>
						<!-- <uni-th align="center" filter-type="timestamp"
							@filter-change="filterChange($event, 'cancel_date')" sortable
							@sort-change="sortChange($event, 'cancel_date')">取消时间</uni-th> -->
						<uni-th align="center" filter-type="search"
							@filter-change="filterChange($event, 'out_trade_no')" sortable
							@sort-change="sortChange($event, 'out_trade_no')">支付插件订单号</uni-th>
						<uni-th align="center">操作</uni-th>
					</uni-tr>
					<uni-tr v-for="(item,index) in data" :key="index">
						<uni-td align="center">{{options.provider_valuetotext[item.provider]}}</uni-td>
						<uni-td align="center">
							<view
								:class="item.status == 1?'col-00ba31':[-1,0,2,3].includes(item.status)?'col-b1':'col-ff4'">
								{{options.status_valuetotext[item.status]}}
							</view>
						</uni-td>
						<uni-td align="center">
							<view v-if="item.nickname || item.user_id">
								<view v-if="item.nickname">昵称：{{item.nickname}}</view>
								<view v-if="item.user_id">ID：{{item.user_id}}</view>
							</view>
							<view v-else>-</view>
						</uni-td>
						<uni-td align="center">
							<view>{{item.description}}</view>
							<view>活动ID：{{item.custom?item.custom.activity_id:''}}</view>
						</uni-td>
						<uni-td align="center">{{item.total_fee/100}}元</uni-td>
						<uni-td align="center">{{item.refund_fee == 0?'-':item.refund_fee/100 + '元'}}</uni-td>
						<uni-td align="center">{{item.user_order_success == true ? '✅' : '❌'}}</uni-td>
						<uni-td align="center">
							<view v-if="item.custom && item.custom.signup_error">
								<view v-for="reason in item.custom.signup_error">
									{{reason}}
								</view>
							</view>
							<view v-else>-</view>
						</uni-td>
						<uni-td align="center">
							<uni-dateformat :threshold="[0, 0]" :date="item.pay_date"></uni-dateformat>
						</uni-td>
						<!-- <uni-td align="center">
							<uni-dateformat :threshold="[0, 0]" :date="item.cancel_date"></uni-dateformat>
						</uni-td> -->
						<uni-td align="center">{{item.out_trade_no}}</uni-td>
						<uni-td align="center">
							<view class="uni-group">
								<button v-if="item.status == 4" @click="toExamine(item)" class="uni-button" size="mini"
									type="primary">审核退款</button>
								<button v-else @click="toExamine(item)" class="uni-button" size="mini"
									type="default">查看</button>
								<!-- <button @click="confirmDelete(item._id)" class="uni-button" size="mini"
									type="warn">删除</button> -->
							</view>
						</uni-td>
					</uni-tr>
				</uni-table>
				<view class="uni-pagination-box">
					<uni-pagination show-icon :page-size="pagination.size" v-model="pagination.current"
						:total="pagination.count" @change="onPageChanged" />
				</view>
			</unicloud-db>
		</view>
		<!-- 审核弹窗 -->
		<view>
			<uni-drawer ref="showRight" mode="right" v-if="drawerWidth" :width="drawerWidth">
				<view class="ping-40">
					<view class="w-100 flex-dir-row ali-item-cen bor-bottom-f3 pb-40" style="align-items: stretch;">
						<view class="shu"></view>
						<view class="fs-32 fw-900 ml-10">报名费用退款审核</view>
					</view>
					<view class="pt-40">
						<view class="flex-dir-row ali-item-cen  mb-40">
							<view class="fs-30 fw-600">申请用户：</view>
							<view class="fs-30">
								{{examineData.nickname && examineData.nickname.length?examineData.nickname: '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen  mb-40">
							<view class="fs-30 fw-600">用户ID：</view>
							<view class="fs-30">
								{{examineData.user_id && examineData.user_id.length?examineData.user_id: '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">用户openid：</view>
							<view class="fs-30">
								{{examineData.openid || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">报名的活动ID：</view>
							<view class="fs-30">
								{{examineData.custom && examineData.custom.activity_id.length?examineData.custom.activity_id: '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">报名的活动名称：</view>
							<view class="fs-30">
								{{examineData.description || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">退款状态：</view>
							<view class="fs-30 ping-15-80"
								:class="examineData.status == 4?'bac-col-4e col-f':[-1,0,2,3].includes(examineData.status)?'bac-col-b1 col-f':'col-87 bac-col-fa'">
								{{options.status_valuetotext[examineData.status]}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">支付金额：</view>
							<view class="fs-30">
								{{examineData.total_fee/100}}元
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">支付时间：</view>
							<view class="fs-30">
								<uni-dateformat :threshold="[0, 0]" :date="examineData.pay_date"></uni-dateformat>
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">已退款金额：</view>
							<view class="fs-30">
								{{examineData.refund_fee/100}}元
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">退款原因：</view>
							<view class="fs-30 col-ff4">
								{{ (examineData && examineData.custom && examineData.custom.refund_reason) || '未知' }}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">订单插件订单号：</view>
							<view class="fs-30">
								{{examineData.out_trade_no || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">业务系统订单号：</view>
							<view class="fs-30">
								{{examineData.order_no || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">微信商户单号：</view>
							<view class="fs-30">
								{{examineData.transaction_id || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">设备ID：</view>
							<view class="fs-30">
								{{examineData.device_id || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">支付IP：</view>
							<view class="fs-30">
								{{examineData.client_ip || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">支付失败原因：</view>
							<view class="fs-30">
								{{examineData.err_msg || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">开放平台appid：</view>
							<view class="fs-30">
								{{examineData.provider_appid || '-'}}
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">订单创建时间：</view>
							<view class="fs-30">
								<uni-dateformat :threshold="[0, 0]" :date="examineData.create_date"></uni-dateformat>
							</view>
						</view>
						<view class="flex-dir-row ali-item-cen mb-40">
							<view class="fs-30 fw-600">回调状态：</view>
							<view class="fs-30">
								{{examineData.user_order_success == true ? '✅' : '❌'}}
							</view>
						</view>
					</view>
					<!-- 审核按钮 -->
					<view v-if="examineData.status == 4" class="flex-dir-row ali-item-cen flex-x-spa mt-40">
						<button style="width: 300rpx;height: 80rpx;line-height: 80rpx;" type="primary" size="mini"
							@click="examine(3)">同意退款</button>
						<button style="width: 300rpx;height: 80rpx;line-height: 80rpx;" class="bac-col-4e col-f br-20"
							size="mini" @click="examine(2)">部分退款</button>
						<button style="width: 300rpx;height: 80rpx;line-height: 80rpx;" type="warn" size="mini"
							@click="examine(1)">拒绝退款</button>
					</view>
				</view>
			</uni-drawer>
		</view>
		<!-- 拒绝原因弹窗 -->
		<uni-popup ref="popupState" type="dialog">
			<uni-popup-dialog mode="input" v-model="refuseReason" title="拒绝原因" placeholder="请输入您拒绝退款的原因"
				@confirm="examine(1)" @close="refuseReason=''">
			</uni-popup-dialog>
		</uni-popup>
		<!-- 部分退款原因弹窗 -->
		<uni-popup ref="popupRefuseReason" type="dialog">
			<uni-popup-dialog mode="input" v-model="refuseReason" title="部分退款原因" placeholder="请输入您部分退款的原因"
				@confirm="examine(2)" @close="refuseReason='',refund_fee=''">
			</uni-popup-dialog>
		</uni-popup>
		<!-- 部分退款金额弹窗 -->
		<uni-popup ref="popupRefundFee" type="dialog">
			<uni-popup-dialog mode="input" v-model="refund_fee" title="部分退款金额" placeholder="请输入您部分退款金额，单位：分"
				@confirm="examine(2)" @close="refund_fee='',refuseReason=''">
			</uni-popup-dialog>
		</uni-popup>
		<uni-pay ref="uniPay"></uni-pay>
	</view>
</template>

<script>
	import {
		enumConverter,
		filterToWhere
	} from '../../js_sdk/validator/uni-pay-orders.js';

	const db = uniCloud.database()
	// 表查询配置
	const dbOrderBy = 'pay_date desc,create_date desc' // 排序字段
	const dbSearchFields = [] // 模糊搜索字段，支持模糊搜索的字段列表。联表查询格式: 主表字段名.副表字段名，例如用户表关联角色表 role.role_name
	// 分页配置
	const pageSize = 20
	const pageCurrent = 1

	const orderByMapping = {
		"ascending": "asc",
		"descending": "desc"
	}

	export default {
		data() {
			return {
				collectionList: "uni-pay-orders",
				query: '',
				where: '',
				orderby: dbOrderBy,
				orderByFieldName: "",
				selectedIndexs: [],
				options: {
					pageSize,
					pageCurrent,
					filterData: {
						"provider_localdata": [{
								"text": "微信支付",
								"value": "wxpay"
							},
							{
								"text": "支付宝",
								"value": "alipay"
							},
							{
								"text": "苹果应用内支付",
								"value": "appleiap"
							},
							{
								"text": "系统钱包",
								"value": "wallet"
							}
						],
						"status_localdata": [{
								"text": "已关闭",
								"value": -1
							},
							{
								"text": "未支付",
								"value": 0
							},
							{
								"text": "已支付",
								"value": 1
							},
							{
								"text": "已部分退款",
								"value": 2
							},
							{
								"text": "已全额退款",
								"value": 3
							},
							{
								"text": "退款中",
								"value": 4
							}
						]
					},
					...enumConverter
				},
				imageStyles: {
					width: 64,
					height: 64
				},
				exportExcel: {
					"filename": "uni-pay-orders.xls",
					"type": "xls",
					"fields": {
						"支付供应商": "provider",
						"订单状态": "status",
						"用户昵称": "nickname",
						"支付描述": "description",
						"订单总金额": "total_fee",
						"订单总退款金额": "refund_fee",
						"回调状态": "user_order_success",
						"自定义数据": "custom",
						"支付时间": "pay_date",
						"取消时间": "cancel_date",
						"支付插件订单号": "out_trade_no"
					}
				},
				exportExcelData: [],
				examineData: {},
				drawerWidth: 800,
				refuseReason: '',
				notice_title: '',
				notice_content: '',
				refund_fee: ''
			}
		},
		onLoad() {
			this._filter = {}
		},
		onReady() {
			this.$refs.udb.loadData()
		},
		mounted() {
			const sysinfo = uni.getSystemInfoSync()
			this.drawerWidth = sysinfo.windowWidth * .8
		},
		methods: {
			// 审核/查看
			toExamine(data) {
				this.$refs.showRight.open();
				this.examineData = data;
			},
			async examine(status) {
				if (status == 1) {
					if (!this.refuseReason) {
						this.$refs.popupState.open();
						return;
					}
					// 拒绝退款，还原订单状态
					await db.collection('uni-pay-orders').doc(this.examineData._id).update({
						status: 1
					});
					this.notice_title = '您的退款申请已被拒绝';
					this.notice_content = this.refuseReason;
					await this.sendNotice();
				} else if (status == 2) {
					// 部分退款原因
					if (!this.refuseReason) {
						this.$refs.popupRefuseReason.open();
						return;
					}
					if (!this.refund_fee) {
						this.$refs.popupRefundFee.open();
						return;
					}
					// 判断退款金额是否为整数
					if (!Number.isInteger(Number(this.refund_fee))) {
						uni.showToast({
							title: '退款金额必须是整数，单位：分',
							icon: 'none'
						})
						return;
					}
					// 如果是微信支付
					let res = null;
					if (this.examineData.provider == 'wxpay') {
						res = await this.$refs.uniPay.refund({
							out_trade_no: this.examineData.out_trade_no, // 插件支付单号
							refund_fee: Number(this.refund_fee), // 退款金额
							refund_desc: this.refuseReason
						});
					} else {
						// 如果是系统钱包
						await db.collection('uni-pay-orders').where({
							out_trade_no: this.examineData.out_trade_no
						}).update({
							status: 2, // 订单状态
							refund_fee: Number(this.refund_fee), // 退款金额
							refund_count: 1, // 退款次数
							refund_list: ['用户取消报名申请退款']
						});
						// 查询用户当前余额
						const userBalance = await db.collection('qmy-user-wallet').where({
							user_id: this.examineData.user_id
						}).orderBy('create_date', 'desc').limit(1).get();
						// 新增用户余额变动记录
						await db.collection('qmy-user-wallet').add({
							user_id: this.examineData.user_id,
							money: Number(this.refund_fee),
							type: 1, // 余额类型
							balance: userBalance.result.data[0].balance + Number(this.refund_fee), // 余额变动
							comment: `活动报名退款`, // 余额变动描述
						});
					}
					if (res?.result?.resultCode == 'SUCCESS' || this.examineData.provider == 'wallet') {
						this.notice_title = '活动退款审核通过';
						this.notice_content = '您报名的活动：' + this.examineData.description.substring(0, this.examineData
								.description.length - 5) + '；已部分退款；部分退款原因：' + this.refuseReason + '；部分退款金额：' + this
							.refund_fee / 100 + '元，请注意查收';
						// 根据活动id和用户id查询报名表，修改报名状态为已取消报名
						await db.collection('qmy-activity-sign-up').where({
							activity_id: this.examineData.custom.activity_id,
							user_id: this.examineData.user_id,
							order_id: this.examineData.out_trade_no
						}).update({
							signup_status: 1
						});
						await this.sendNotice();
					} else {
						uni.showToast({
							title: '操作失败，请检查商户内余额是否充足',
							icon: 'none'
						})
						return;
					}

				} else if (status == 3) {
					let res = null;
					// 同意退款
					if (this.examineData.provider == 'wxpay') {
						res = await this.$refs.uniPay.refund({
							out_trade_no: this.examineData.out_trade_no, // 插件支付单号
						});
					} else {
						// 如果是系统钱包
						await db.collection('uni-pay-orders').where({
							out_trade_no: this.examineData.out_trade_no
						}).update({
							status: 3, // 订单状态
							refund_fee: this.examineData.total_fee, // 退款金额
							refund_count: 1, // 退款次数
							refund_list: ['用户取消报名申请退款']
						});
						// 查询用户当前余额
						const userBalance = await db.collection('qmy-user-wallet').where({
							user_id: this.examineData.user_id
						}).orderBy('create_date', 'desc').limit(1).get();
						console.log('userBalance: ', userBalance)
						// 新增用户余额变动记录
						await db.collection('qmy-user-wallet').add({
							user_id: this.examineData.user_id,
							money: Number(this.examineData.total_fee),
							type: 1, // 余额类型
							balance: userBalance.result.data[0].balance + Number(this.examineData
							.total_fee), // 余额变动
							comment: `活动报名退款`, // 余额变动描述
						});
					}
					if (res?.result?.resultCode == 'SUCCESS' || this.examineData.provider == 'wallet') {
						// 根据活动id和用户id查询报名表，修改报名状态为已取消报名
						await db.collection('qmy-activity-sign-up').where({
							activity_id: this.examineData.custom.activity_id,
							user_id: this.examineData.user_id,
							order_id: this.examineData.out_trade_no
						}).update({
							signup_status: 1
						});
						this.notice_title = '活动退款审核通过';
						this.notice_content = '您报名的活动：' + this.examineData.description.substring(0, this.examineData
								.description.length - 5) + '；已全额退款；退款金额：' + this.examineData.total_fee / 100 +
							'元；请注意查收；希望我们的服务能让您满意，祝您生活愉快！';
						await this.sendNotice();
					} else {
						uni.showToast({
							title: '操作失败，请检查商户内余额是否充足',
							icon: 'none'
						})
						return;
					}
				}
				uni.showToast({
					title: '审核成功',
					icon: 'none'
				})
				setTimeout(() => {
					this.$refs.showRight.close();
					this.$nextTick(() => {
						this.loadData();
					})
				}, 1000);
			},
			// 发送通知
			async sendNotice() {
				// 给用户发送审核结果通知
				await db.collection('qmy-notice').add({
					receive_user_id: this.examineData.user_id,
					notice_type: 0,
					system_notice_type: '退款审核结果通知',
					notice_title: this.notice_title,
					notice_content: this.notice_content,
					user_read_status: 0,
				}).then(() => {
					this.notice_title = '';
					this.notice_content = '';
					this.refuseReason = '';
					this.refund_fee = '';
				}).catch(err => {
					uni.showToast({
						title: '通知发送失败,' + err.errMsg,
						icon: 'none'
					})
				})
				this.refuseReason = '';
			},
			onqueryload(data) {
				this.exportExcelData = data
			},
			getWhere() {
				const query = this.query.trim()
				if (!query) {
					return ''
				}
				const queryRe = new RegExp(query, 'i')
				return dbSearchFields.map(name => queryRe + '.test(' + name + ')').join(' || ')
			},
			search() {
				const newWhere = this.getWhere()
				this.where = newWhere
				this.$nextTick(() => {
					this.loadData()
				})
			},
			loadData(clear = true) {
				this.$refs.udb.loadData({
					clear
				})
			},
			onPageChanged(e) {
				this.selectedIndexs.length = 0
				this.$refs.table.clearSelection()
				this.$refs.udb.loadData({
					current: e.current
				})
			},
			navigateTo(url, clear) {
				// clear 表示刷新列表时是否清除页码，true 表示刷新并回到列表第 1 页，默认为 true
				uni.navigateTo({
					url,
					events: {
						refreshData: () => {
							this.loadData(clear)
						}
					}
				})
			},
			// 多选处理
			selectedItems() {
				var dataList = this.$refs.udb.dataList
				return this.selectedIndexs.map(i => dataList[i]._id)
			},
			// 批量删除
			delTable() {
				this.$refs.udb.remove(this.selectedItems(), {
					success: (res) => {
						this.$refs.table.clearSelection()
					}
				})
			},
			// 多选
			selectionChange(e) {
				this.selectedIndexs = e.detail.index
			},
			confirmDelete(id) {
				this.$refs.udb.remove(id, {
					success: (res) => {
						this.$refs.table.clearSelection()
					}
				})
			},
			sortChange(e, name) {
				this.orderByFieldName = name;
				if (e.order) {
					this.orderby = name + ' ' + orderByMapping[e.order]
				} else {
					this.orderby = ''
				}
				this.$refs.table.clearSelection()
				this.$nextTick(() => {
					this.$refs.udb.loadData()
				})
			},
			filterChange(e, name) {
				this._filter[name] = {
					type: e.filterType,
					value: e.filter
				}
				let newWhere = filterToWhere(this._filter, db.command)
				if (Object.keys(newWhere).length) {
					this.where = newWhere
				} else {
					this.where = ''
				}
				this.$nextTick(() => {
					this.$refs.udb.loadData()
				})
			}
		}
	}
</script>

<style>
</style>